package llc.ufwa.unlimitedlist.activities.list;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

import llc.ufwa.concurrency.Callback;
import llc.ufwa.concurrency.CallbackFinalizer;
import llc.ufwa.concurrency.DefaultCallbackFinalizer;
import llc.ufwa.concurrency.WeakCallback;
import llc.ufwa.data.exception.ResourceException;
import llc.ufwa.data.resource.loader.BatchingParallelResourceLoader;
import llc.ufwa.data.resource.loader.ResourceEvent;
import llc.ufwa.unlimitedlist.MainApplication;
import llc.ufwa.unlimitedlist.R;
import llc.ufwa.unlimitedlist.data.UnlimitedListItem;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class ListAdapter extends BaseAdapter {
	
	private static final Logger logger = LoggerFactory.getLogger(ListAdapter.class);
	
	private final List<ListKey> keys;
	private final Context context;
	private final BatchingParallelResourceLoader<Long, UnlimitedListItem> batchedItems;
	private final BatchingParallelResourceLoader<Long, UnlimitedListItem> previousBatchedItems;

	private final CallbackFinalizer finalizer = new DefaultCallbackFinalizer();
	private final Executor uiRunner;
	
	public ListAdapter(
	    final Context context,
	    final Executor uiRunner,
	    final List<ListKey> keys
	) {
		
		this.uiRunner = uiRunner;
		this.keys = keys;
		this.context = context;
		
		final MainApplication application = (MainApplication)context.getApplicationContext();
		
		final int BATCH_SIZE = 10;
        final int RADIUS = 20;
        
        final List<Long> ids = new ArrayList<Long>();
        
        for(final ListKey key : keys) {
        	ids.add(key.getID());
        }
        
        {
            
            final BatchingParallelResourceLoader<Long, UnlimitedListItem> batched = 
                    new BatchingParallelResourceLoader<Long, UnlimitedListItem>(
                        application.getItemsLoader(), 
                        BATCH_SIZE, 
                        RADIUS, 
                        application.getItemsLoader().getSearchCache(),
                        application.getItemsLoader().getCache(),
                        ids
                    );
            
            this.batchedItems = batched;
            
        }
        
        {
            
            final BatchingParallelResourceLoader<Long, UnlimitedListItem> batched = 
                    new BatchingParallelResourceLoader<Long, UnlimitedListItem>(
                        application.getPreviousItems(), 
                        BATCH_SIZE, 
                        RADIUS, 
                        application.getPreviousItems().getSearchCache(),
                        application.getPreviousItems().getCache(),
                        ids
                    );
            
            this.previousBatchedItems = batched;
            
        }
	}

	@Override
	public int getCount() {
		return keys.size();
	}

	@Override
	public ListKey getItem(int index) {
		return keys.get(index);
	}

	@Override
	public long getItemId(int index) {
		return getItem(index).getID();
	}

	@Override
	public View getView( 
       final int arg0,
       final View arg1, 
       final ViewGroup arg2
    ) {
		
		final LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		
		final View root;
		
		if(arg1 == null) {
			root = inflater.inflate(R.layout.title, null, false);
		}
		else {
			root = arg1;
		}
		
		final TextView title = (TextView)root.findViewById(R.id.title);
		final ImageView image = (ImageView) root.findViewById(R.id.image);
		
		image.setImageResource(R.drawable.ic_launcher);
		
		title.setText("----");
		title.setTag(String.valueOf(arg0));
		
		final MainApplication application = (MainApplication)context.getApplicationContext();
		
		try {
		batchedItems.getParallel(
			    new WeakCallback<Object, ResourceEvent<UnlimitedListItem>>(	
				    new Callback<Object, ResourceEvent<UnlimitedListItem>>() {

						@Override
						public boolean call(
						    final Object source,
							final ResourceEvent<UnlimitedListItem> value
					    ) {
							
							logger.debug("callback for key: " + arg0);
							
							if(value.getVal() != null) {
								
								logger.debug("wasnt null for key: " + arg0);
								
								uiRunner.execute(
								    new Runnable() {

										@Override
										public void run() {
											
											logger.debug("on ui for key: " + arg0);
											
											if(title.getTag().equals(String.valueOf(arg0))) {
												
												logger.debug("proper tag for key: " + arg0);
												
												final TextView title = (TextView)root.findViewById(R.id.title);
												final ImageView image = (ImageView) root.findViewById(R.id.image);
												
												title.setText(String.valueOf(value.getVal().getID()));
												
												final byte [] data = value.getVal().getData();
												
												final Bitmap bmp =
											        BitmapFactory.decodeByteArray(data, 0, data.length);
												
												image.setImageBitmap(bmp);
												
											}
											
										}
										
								    }
								    
								);
								
							}
							
							return false;
						}
				    },
				    false,
				    finalizer
				),
			    (long)arg0
			);
		} 
		catch (ResourceException e) {
			
			logger.error("ERROR: ", e);
			
			title.setText("ERROR " + e.getMessage());
		}
		
		return root;
		
	}

}
